package com.xyy.saas.payment.adpater.unionpay;

import com.alibaba.fastjson.JSON;
import com.xyy.saas.payment.adpater.pingxx.domain.PayDO;
import com.xyy.saas.payment.adpater.pingxx.domain.RefundDO;
import com.xyy.saas.payment.callback.core.handler.CastRequestHandler;
import com.xyy.saas.payment.common.Constants;
import com.xyy.saas.payment.cores.enums.PayModeEnum;
import com.xyy.saas.payment.util.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author wangtianqi
 * @date 2020/7/7 16:08
 */
@Component
public class CastUnionPayRequestHandler implements CastRequestHandler {

    private static final org.slf4j.Logger LOGGER = org.slf4j.LoggerFactory.getLogger(CastUnionPayRequestHandler.class);

    @Override
    public String getChannel() {
        return Constants.CHANNEL_UNIONPAY_NAME;
    }

    @Override
    public Object castRequestHandler(String method, Map<String, String> request, HttpServletRequest requestMsg) throws Exception {
        Object domain = null;
        switch (method) {
            case Constants.METHOD_PAY_SUCCESS_NAME :
                domain = castToPayDo(requestMsg);
                break;
            case Constants.METHOD_REFUND_SUCCESS :
                domain = castToRefundDO(requestMsg);
                break;
            default:
                LOGGER.error("CastUnionPayRequestHandler#castRequestHandler unrecognized method:{} request:{}", method, JSON.toJSONString(request));
                break;
        }
        return domain;
    }

    private PayDO castToPayDo(HttpServletRequest requestMsg) {
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestParams = requestMsg.getParameterMap();
        exactParams(params, requestParams);

        //商户订单号
        String payNo = params.get("orderId");
        //返回code
        String respCode = params.get("respCode");
        Integer amount = Integer.parseInt(params.get("txnAmt"));
        String channelTransactionNo = params.get("queryId");
        String channelType = params.get("reqReserved");

        PayDO domain = new PayDO();
        domain.setOrderNo(payNo);
        domain.setChannelChargeNo(channelTransactionNo);
        domain.setAmount(amount);
        domain.setChannel(Constants.CHANNEL_DIRECT_NAME + "_" + Constants.CHANNEL_UNIONPAY_NAME);
        if("00".equals(respCode)){
            domain.setResultCode("SUCCESS");
        }else{
            domain.setResultCode("FAIL");
        }

        if("07".equals(channelType)){
            domain.setPayMode(PayModeEnum.ONLINE_GW.getMode());
        }else if("08".equals(channelType)){
            domain.setPayMode(PayModeEnum.APP_WAP.getMode());
        }

        domain.setChannelTransactionNo(channelTransactionNo);
        return domain;
    }

    private void exactParams(Map<String, String> params, Map<String, String[]> requestParams) {
        requestParams.forEach((key, values) -> {
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            params.put(key, valueStr);
        });
    }

    /**
     * 退款对象
     * @param requestMsg
     * @return
     */
    private RefundDO castToRefundDO(HttpServletRequest requestMsg) {
        RefundDO domain = new RefundDO();
        try {
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = requestMsg.getParameterMap();
            exactParams(params, requestParams);
            //商户订单号
            String refundNo = params.get("orderId");
            domain.setRefundNo(refundNo);
            String returnCode = params.get("respCode");
            domain.setSucceed(true);
            if(!"00".equals(returnCode)){
                domain.setSucceed(false);
            }
            //第三方退款单号
            domain.setId(params.get("queryId"));
            domain.setTimeSucceed(StringUtils.isNotEmpty(params.get("txnTime")) ? DateUtil.parase(params.get("txnTime"),DateUtil.YYYYMMDDHHMMSS) : new Date());
        } catch (Exception e){
            LOGGER.error("CastUnionPayRequestHandler.castToRefundDO error：",e);
        }
        return domain;
    }

}
